#include <stdlib.h>
#include <wiiuse/wpad.h>
#include "gfxUtils.h"
#include "font.h"
#include "widgets.h"


const GXColor borderColor = {100, 100, 100, 0xFF};
const GXColor fillColor = {105, 120, 154, 0xFF};
const GXColor selectColor = {200, 200, 10, 0xFF};

#define BORDERGAP_X 64
#define BORDERGAP_Y 48

//draws a button
// text size is button height-10
void drawButton(int x, int y, int width, int height, const char* text, bool selected = false)
{
	int xPos = x+(width-defaultFont->getTextWidth(text, height-10))/2;
	defaultFont->drawText(xPos, y+5, text, height-10);
	if(selected)
	{
		drawRect(x, y, width, height, selectColor, false);
	}
}

// preconditions : somebody set the default font
int selectionMenu(char* title, char* selections[], int numSel, int defaultSel)
{
	int select = defaultSel;
	const int jump = title?((480-4.5*BORDERGAP_Y-40)/numSel):((480-4*BORDERGAP_Y)/numSel);
	const int fontGap = (jump-(30))/2;
	
	while(1) {
		// Call WPAD_ScanPads each loop, this reads the latest controller states
		WPAD_ScanPads();

		// WPAD_ButtonsDown tells us which buttons were pressed in this loop
		// this is a "one shot" state which will not fire again until the button has been released
		u32 pressed = WPAD_ButtonsDown(0);

		if ( pressed & WPAD_BUTTON_RIGHT )
		{
			if((--select)<0)		// wraparound
			{
				select = numSel-1;
			}
		}
		if ( pressed & WPAD_BUTTON_LEFT )
		{
			if((++select)>=numSel)	// wraparound
			{
				select = 0;
			}
		}
		if ( pressed & WPAD_BUTTON_2 )
		{
			break;
		}

		// render the menu
		// draw the box
		drawRect(BORDERGAP_X, BORDERGAP_Y, 640-2*BORDERGAP_X, 480-2*BORDERGAP_Y, fillColor, true);
		drawRect(BORDERGAP_X, BORDERGAP_Y, 640-2*BORDERGAP_X, 480-2*BORDERGAP_Y, borderColor, false);

		int yPos;
		if(title)
		{
			// draw title
			yPos =1.5*BORDERGAP_Y;
			defaultFont->drawText(BORDERGAP_X*2.5, yPos, title, 40);
			yPos+=40;
			yPos+=BORDERGAP_Y;
		}
		else
		{
			yPos = 2*BORDERGAP_Y;
		}

		// draw the options
		for(int i=0; i<numSel; ++i)
		{
			defaultFont->drawText(BORDERGAP_X*2.5, yPos+fontGap+i*jump, selections[i], 30);
		}
		drawRect(BORDERGAP_X*2, yPos+select*jump, 640-BORDERGAP_X*4, jump, selectColor, false);
		
		renderToFrameBuffer(getSpareFrameBuffer());
		swapFrameBuffers();
		waitVSync();

	}
	return select;	// unused
}

bool messageBox(const char* msg, const char* left, const char* right)
{
	bool rightSelected = false;
	while(1) {

		// Call WPAD_ScanPads each loop, this reads the latest controller states
		WPAD_ScanPads();

		// WPAD_ButtonsDown tells us which buttons were pressed in this loop
		// this is a "one shot" state which will not fire again until the button has been released
		u32 pressed = WPAD_ButtonsDown(0);

		if ( pressed & WPAD_BUTTON_UP )
		{
			rightSelected = false;
		}
		if ( pressed & WPAD_BUTTON_DOWN )
		{
			rightSelected = true;
		}
		if ( pressed & WPAD_BUTTON_2 )
		{
			break;
		}
		// render the menu
		// draw the box
		drawRect(BORDERGAP_X, BORDERGAP_Y, 640-2*BORDERGAP_X, 480-2*BORDERGAP_Y, fillColor, true);
		drawRect(BORDERGAP_X, BORDERGAP_Y, 640-2*BORDERGAP_X, 480-2*BORDERGAP_Y, borderColor, false);
		defaultFont->drawText(BORDERGAP_X*2.5, 2*BORDERGAP_Y, msg, 30);

		if(right)
		{
			drawButton(BORDERGAP_X*2, 480-2*BORDERGAP_Y-40, 320-3*BORDERGAP_X, 30+20, left, !rightSelected);
			drawButton(320+BORDERGAP_X, 480-2*BORDERGAP_Y-40, 320-3*BORDERGAP_X, 30+20, right, rightSelected);
		}
		else
		{
			int xPos = 320-defaultFont->getTextWidth(left, 30)/2-10;
			drawButton(xPos, 480-2*BORDERGAP_Y-40, defaultFont->getTextWidth(left, 30)+20, 30+20, left, true);
		}
		
		renderToFrameBuffer(getSpareFrameBuffer());
		swapFrameBuffers();
		waitVSync();	
	}
	return rightSelected;
}

void infoBox(const char* title, const char* msg)
{
#define UPTRI_BASE (2.5*BORDERGAP_Y+10)
#define DNTRI_BASE (480-1.5*BORDERGAP_Y-55)
	const int upTri[] = {320-10, UPTRI_BASE, 320, UPTRI_BASE-10, 320+10, UPTRI_BASE};
	const int dnTri[] = {320-10, DNTRI_BASE, 320, DNTRI_BASE+10, 320+10, DNTRI_BASE};
	int yPos = UPTRI_BASE+5;
	int tempY = yPos;
	const char* tempMsg;
	while(1) {

		// Call WPAD_ScanPads each loop, this reads the latest controller states
		WPAD_ScanPads();

		// WPAD_ButtonsDown tells us which buttons were pressed in this loop
		// this is a "one shot" state which will not fire again until the button has been released
		u32 pressed = WPAD_ButtonsDown(0);
		if ( pressed & WPAD_BUTTON_LEFT && tempY>DNTRI_BASE-5 )
		{
			yPos-=20;
		}
		if ( pressed & WPAD_BUTTON_RIGHT && yPos<UPTRI_BASE+5 )
		{
			yPos+=20;
		}
		if ( pressed & WPAD_BUTTON_2)
		{
			break;
		}
		// render the menu
		// draw the box
		drawRect(BORDERGAP_X, BORDERGAP_Y, 640-2*BORDERGAP_X, 480-2*BORDERGAP_Y, fillColor, true);
		drawRect(BORDERGAP_X, BORDERGAP_Y, 640-2*BORDERGAP_X, 480-2*BORDERGAP_Y, borderColor, false);
		
		// title
		defaultFont->drawText(320-defaultFont->getTextWidth(title, 35)/2, 1.5*BORDERGAP_Y, title, 35);

		GX_SetScissor(BORDERGAP_X*1.5, UPTRI_BASE+5, 640-BORDERGAP_X*3, DNTRI_BASE-UPTRI_BASE-10);
		tempY = yPos;
		tempMsg = msg;
		while(*tempMsg)
		{
			tempMsg+=defaultFont->drawText(BORDERGAP_X*1.5, tempY, tempMsg, 20);
			tempY+=20;
			if(*tempMsg=='\n')
			{
				++tempMsg;
			}
		}
		
		GX_SetScissor(0, 0, 640, 480);
		drawShape(upTri, 3, yPos<2.5*BORDERGAP_Y?selectColor:borderColor, true);
		drawShape(dnTri, 3, tempY>(480-1.5*BORDERGAP_Y-60)?selectColor:borderColor, true);
	
		drawButton(250, 480-1.5*BORDERGAP_Y-30, 140, 30, "OK", true);
		
		renderToFrameBuffer(getSpareFrameBuffer());
		swapFrameBuffers();
		waitVSync();	
	}
}
